﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Linq;
using System.ComponentModel;
using FinPlusCommon;
using log = Logger.Logger;

namespace FinPlusComponents
{
    public class FinPlusMarket: FinPlusComponent
    {
        public override string[] TestStates { get { return new string[] { "TestString", "IsValid" }; } }
        public override IFunctions Adaptor { get { return _instrumentConn.Adaptor; } }
        public override string TestString { get { return Adaptor.ToString(); } }

        private enum Params { LevelUpdate, Refresh, MarketUpdate, Level, BuySell, Shock, Instrument, Tag }
        private readonly IFinPlusComp _marketLevelConn, _instrumentConn;
        private readonly string _tag;

        //construct
        public FinPlusMarket(IFinPlusComp instruments, IFinPlusComp marketLevels, string tag)
        {
            _tag = tag;
            _instrumentConn = instruments;
            _marketLevelConn = marketLevels;

            _instrumentConn.Adaptor.Get(Params.Shock.ToString(), new Function());
            _instrumentConn.Adaptor.Get(Params.LevelUpdate.ToString(), new Function());
            _instrumentConn.Adaptor.Get(Params.Refresh.ToString(), string.Empty, Level_Refresh);

            RefreshAll();
            
            IsValid =  true;
        }

        //common control interface
        public override void CmdExecute(IFunction command)
        {
            try
            {
                CmdCapture(command);

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.Refresh: Refresh(command[Params.Tag.ToString()].ToString()); break;
                    default: throw new Exception(string.Format("event not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
                IsValid = log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        public override void Dispose()
        {
            if (_instrumentConn != null)
                _instrumentConn.Dispose();

            if (_marketLevelConn != null)
                _marketLevelConn.Dispose();
        }

        //private
        private void Refresh(string instrumentName)
        {
            var instrument = _instrumentConn.Adaptor.First(string.Format("Name='Instrument' And Value='{0}'", instrumentName));
            Refresh(instrument);
        }

        private void Refresh(IFunction instrument)
        {
            if (instrument == null) 
                return;

            var marketLevels = _marketLevelConn.Adaptor.Values.Where(f => f[Params.Instrument.ToString()].Equals(instrument[Params.Instrument.ToString()]));
            foreach (var marketLevel in marketLevels)
            {
                instrument.Get(Params.LevelUpdate.ToString()).Set(marketLevel);
                instrument.Get(string.Format("{0}{1}", _tag, marketLevel[Params.BuySell.ToString()].ToString()), 0.0).Set((double)marketLevel.Value(Params.Level.ToString()));
            }
        }

        private void RefreshAll()
        {
            foreach (var inst in _instrumentConn.Adaptor.Values)
                Refresh(inst);
        }
       
        //cmds 
        private enum Cmds { Refresh }

        //events 
        private void Level_Refresh(object s, PropertyChangedEventArgs a) 
        {
            CmdExecute(new Function(Cmds.Refresh.ToString(), Id, User, -1, ((IItem)s).Value));
        }
    }
}
